#pragma once
#ifdef LIT_OGRE_SUPPORT

#ifndef __LIT__MESH__INCLUDED__HH__
#define __LIT__MESH__INCLUDED__HH__

#include <LitPrerequisites.h>
#include <OgreMesh.h>
#include <OgreSubMesh.h>
#include <OgreMeshManager.h>

namespace Lit
{
	class LIT_API MeshDeclaration
	{
	public:
		struct Vertex
		{
			Vertex();
			Vertex( const Lit::Vec3 &pos, const Lit::Vec3& norm=Lit::Vec3::ZERO, const Lit::Vec3& tang=Lit::Vec3::ZERO);

			Lit::Vec3					position;
			std::pair<Lit::Vec3, bool>	normal;
			std::pair<Lit::Vec3, bool>	tangent;
		};
		struct Element
		{
			Element( Ogre::VertexElementType type_, Ogre::VertexElementSemantic semantic_ );
			Element( const Element& rk );
			~Element();

			void setOffset( size_t off );
			size_t getTypeSize() const;

			Ogre::VertexElementType			type;
			Ogre::VertexElementSemantic		semantic;
			size_t							offset;
		};
		typedef std::vector<Element>	 ElementList;
		typedef std::vector<Vertex>		 VertexList;
		typedef std::vector<uint16_t>	 IndexList;

	private:
		ElementList m_list;
		VertexList  m_verts;
		IndexList	m_inds;
		size_t		m_offset;
		String	m_name;
	public:
		MeshDeclaration( const String &name = "" ) ;
		MeshDeclaration( const MeshDeclaration& rk ) ;
		~MeshDeclaration();

		const String &getName() const;

		void uploadElements(Ogre::VertexDeclaration *decl);
		MeshDeclaration* addVertex( const Vertex& vert );
		MeshDeclaration* addIndex( uint16_t id );
		MeshDeclaration* addElement( const Element& elem );
		void cleanup();
		size_t getNumElements() const;
		bool hasElements() const;
			
		size_t getNumVertices() const;
		bool hasVertices() const;

		size_t getNumIndices() const;
		bool hasIndices() const;
			
		uint16_t& getIndex( size_t id );
		const uint16_t& getIndex( size_t id ) const;

		Element& getElement( size_t id );
		const Element& getElement( size_t id ) const;

		Vertex& getVertex( size_t id );
		const Vertex& getVertex( size_t id ) const;
			
		ElementList& getElements();
		VertexList& getVertices();
		IndexList& getIndices();
		const ElementList& getElements()const;
		const VertexList& getVertices()const;
		const IndexList& getIndices()const;

		size_t getOffset() const;
	};
	typedef Lit::RefPtr<MeshDeclaration> MeshDeclarationPtr;

	class LIT_API MeshBuilder
	{
	public:
		MeshBuilder( );
		virtual ~MeshBuilder();
			
		static Ogre::MeshPtr create( MeshDeclarationPtr decl, const String &res_grp=Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME );
	};
};

#endif

#endif // IF DEFINED LIT_OGRE_SUPPORT